
function Chart() {

    // 配置项
    this.marginTop = 30;
    this.marginBottom = 10;
    this.marginLeft = 10;
    this.marginRight = 16;
    this.chartMarkerWidth = 5;
    this.chartDottedLineWidth = 8;
    this.chartDataPointGap = 25;
    this.chartDataPointRadius = 4;
    this.chartDataPointFillStyle = "limegreen";
    this.chartDataPointLineFillStyle = "limegreen";
    this.chartUslLineStrokeStyle = "red";
    this.chartUclLineStrokeStyle = "red";
    //this.chartTargetLineStrokeStyle = "fuchsia";
    this.chartTargetLineStrokeStyle = "#0000ff";
    this.chartLclLineStrokeStyle = "red";
    this.chartLslLineStrokeStyle = "red";
    this.chartSpecLabelMarginRight = 4;
    this.chartSpecLabelFont = "sans-serif";
    this.chartSpecLabelFontHeight = 14;
    this.chartSpecLabelFontStyle = "normal";
    this.chartUslLabelFillStyle = "red";
    this.chartUclLabelFillStyle = "red";
    this.chartTargetLabelFillStyle = "fuchsia";
    this.chartLclLabelFillStyle = "red";
    this.chartLslLabelFillStyle = "red";
    this.chartXYAxisStokeStyle = "black";
    this.chartXYAxisLineWidth = 2;
    this.chartSpecLineWidth = 1;
    this.dataPointSelectedLineWidth = 1;
    this.dataPointSelectedLineStrokeStyle = "RoyalBlue";
    this.chartPointCommentTriangleRadius = 10;
    this.chartPointCommentTriangleFillStyle = "tomato";
    this.chartHeaderInformationFillStyle = "black";
    this.chartHeaderInformationFont = "fantasy";
    this.chartHeaderInformationFontHeight = 18;
    this.chartHeaderInformationFontStyle = "normal";
    this.yAxisLabelFillStyle = "black";
    this.yAxisLabelFont = "sans-serif";
    this.yAxisLabelFontHeight = 12;
    this.yAxisLabelFontStyle = "normal";
    this.yAxisLabelMargin = 5;

    // 非配置项
    this.data = null;
    this.upl = 0;
    this.usl = 0;
    this.ucl = 0;
    this.target = 0;
    this.lcl = 0;
    this.lsl = 0;
    this.lpl = 0;
    this.gname = null;
    this.cname = null;
    this.ctitle = null;
    this.chart_typ = null;
    this.chart_typ_dsc = null;
    this.point = new Array();
    this.canvas = null;
    this.context = null;
    this.chartCount = 0;
    this.chartIndex = 0;
    this.canvasWidth = 0;
    this.canvasHeight = 0;
    this.chartWidth = 0;
    this.chartHeight = 0;
    this.chartTopLeftX = 0;
    this.chartTopLeftY = 0;
    this.chartTopLeftForFirstChartX = 0;
    this.chartTopLeftForFirstChartY = 0;
    this.dataPointCoordinateOneTwoThree = new Array(); //marked by xinlin    //liufang test
    this.dataPointCoordinateArray = new Array(); //add by xinlin
    this.clickChartSequence = 0;
    //add by lin.xin
    this.mean=0;
    this.stdDev =0;
    this.sigma  =0;
    this.sigma_ppk =0;
    this.ppk=0;
    this.pp=0;
    this.ca =0;
    this.cpk=0;
    this.cp=0;
    this.grade="A";

    // 初始化画板
    this.initializeCanvas = function(canvasElement, canvasWidth, canvasHeight,isShareOneCanvas,pointCnt) {

        this.canvas = document.getElementById(canvasElement);
        this.context = this.canvas.getContext("2d");
        this.canvasWidth = this.chartDataPointGap*pointCnt > 1222 ? this.chartDataPointGap*pointCnt + 120 : canvasWidth;

        this.canvasHeight = canvasHeight;
        if( isShareOneCanvas == true){
            return ;
        }
        this.canvas.width = canvasWidth;
        this.canvas.height = canvasHeight;
        $(this.canvas).attr("width",this.canvasWidth);
        $(this.canvas).attr("height",this.canvasHeight);

    };

    this.initializeChart = function(data, chartCount, chartIndex) {

        // 赋值全局变量
        var context = this.context;
        this.data = data;
        this.chartCount = chartCount;
        this.chartIndex = chartIndex;
        this.upl = data.upl;
        this.usl = data.usl;
        this.ucl = data.ucl;
        this.target = data.target;
        this.lcl = data.lcl;
        this.lsl = data.lsl;
        this.lpl = data.lpl;
        this.gname = data.gname;
        this.cname = data.cname;
        this.ctitle = data.ctitle;
        this.chart_typ = data.chart_typ;
        this.chart_unit = data.cunit;

        // 计算Y轴标签的值
        var yAxisLabelValue = new Array();
        for ( var i = 0; i <= 10; i++) {
            if (i == 0) {
                yAxisLabelValue.push(this.lpl.toFixed(2));
            } else {
                yAxisLabelValue.push((this.lpl + i * (this.upl - this.lpl) / 10).toFixed(2));
            }
        }

        // 计算Y轴标签的最大宽度
        var YAxisLabelWidth = 0;
        var maxYAxisLabelWidth = 0;
        for ( var i = 0; i < yAxisLabelValue.length; i++) {
            YAxisLabelWidth = context.measureText(yAxisLabelValue[i]).width;
            if (YAxisLabelWidth > maxYAxisLabelWidth) {
                maxYAxisLabelWidth = YAxisLabelWidth;
            }
        }

        // 计算各个块及控制图的宽高
        this.tileWidth = this.canvasWidth;
        this.tileHeight = this.canvasHeight / chartCount;
        this.chartWidth = this.tileWidth - this.marginLeft - maxYAxisLabelWidth - this.yAxisLabelMargin - this.chartMarkerWidth - this.marginRight;
        this.chartHeight = this.tileHeight - this.marginTop - this.marginBottom;

        // 计算Y轴顶端的坐标
        if (chartIndex == 1) {
            this.chartTopLeftForFirstChartX = this.marginLeft + maxYAxisLabelWidth + this.yAxisLabelMargin + this.chartMarkerWidth;
            this.chartTopLeftForFirstChartY = this.tileHeight * (chartIndex - 1) + this.marginTop;
        }
        this.chartTopLeftX = this.marginLeft + maxYAxisLabelWidth + this.yAxisLabelMargin + this.chartMarkerWidth;
        this.chartTopLeftY = this.tileHeight * (chartIndex - 1) + this.marginTop;

        // 画控制图的背景
        context.save();
        context.translate(this.chartTopLeftX, this.chartTopLeftY);
        context.save();
        var linearGradient = context.createLinearGradient(0, 0, 0, this.canvasWidth);
        linearGradient.addColorStop(0.2, '#fdfdfd');
        linearGradient.addColorStop(0.8, '#ededed');
        context.fillStyle = linearGradient;
        context.fillRect(0, 0, this.chartWidth, this.chartHeight);

        // 画控制图的轴线（边框）
        context.restore();
        context.strokeStyle = this.chartXYAxisStokeStyle;
        context.lineWidth = this.chartXYAxisLineWidth;
        context.strokeRect(0, 0, this.chartWidth, this.chartHeight);

        // 画控制图的简要信息
        context.save();
        context.textBaseline = "bottom";
        context.font = this.chartHeaderInformationFontStyle + " " + this.chartHeaderInformationFontHeight + "px " + this.chartHeaderInformationFont;
        context.fillStyle = this.chartHeaderInformationFillStyle;
        // 先定义样式，再计算文本长度才准确
        //定义chart图标题
        switch(this.chart_typ){
            case "01" : this.chart_typ_dsc = "M";break;
            case "02" : this.chart_typ_dsc = "RG";break;
            case "03" : this.chart_typ_dsc = "SG";break;
            case "04" : this.chart_typ_dsc = "UN";break;
            case "10" : this.chart_typ_dsc = "SI";break;
            case "11" : this.chart_typ_dsc = "MR";break;
            case "30" : this.chart_typ_dsc = "MD";break; //liufang
            case "31" : this.chart_typ_dsc = "MR";break; //liufang
            case "40" : this.chart_typ_dsc = "P" ;break;  //liufang
            case "50" : this.chart_typ_dsc = "NP";break;  //liufang
            case "60" : this.chart_typ_dsc = "C" ;break;   //liufang
        }
        var chartHeaderInformation = this.cname +"-" + this.chart_typ_dsc + " | " + this.ctitle + " | " + this.gname + " | " + "单位:"+ this.chart_unit;
        var chartHeaderInformationStartX = (this.chartWidth - context.measureText(chartHeaderInformation).width) / 2;
        context.translate(chartHeaderInformationStartX, 0);
        context.fillText(chartHeaderInformation, 0, 0);
        context.restore();

        // 计算Y轴的刻度和标签
        var yAxisStep = this.chartHeight / 10;
        var markerY = 0;
        var labelX = 0;
        var labelY = 0;
        for ( var i = 0; i <= 10; i++) {
            if (i != 0 && i != 10) {
                // 画刻度
                context.beginPath();
                context.moveTo(0, markerY);
                context.lineTo(-this.chartMarkerWidth, markerY);
                context.stroke();
            }

            // 画标签
            context.font = this.yAxisLabelFontStyle + " " + this.yAxisLabelFontHeight + "px " + this.yAxisLabelFont;
            context.fillStyle = this.yAxisLabelFillStyle;
            context.textBaseline = "middle";
            labelX = -this.chartMarkerWidth - maxYAxisLabelWidth - this.yAxisLabelMargin;
            labelY = markerY;
            labelValue = yAxisLabelValue[10 - i];
            context.fillText(yAxisLabelValue[10 - i], labelX, labelY);
            markerY += yAxisStep;
        }

        // 画控制图的上规格线
        context.beginPath();
        context.moveTo(0, this.chartHeight * (this.upl - this.usl) / (this.upl - this.lpl));
        context.lineTo(this.chartWidth, this.chartHeight * (this.upl - this.usl) / (this.upl - this.lpl));
        context.lineWidth = this.chartSpecLineWidth;
        context.strokeStyle = this.chartUslLineStrokeStyle;
        context.stroke();

        // 画控制图的上规格线标签
        context.font = this.chartSpecLabelFontStyle + " " + this.chartSpecLabelFontHeight + "px " + this.chartSpecLabelFont;
        context.fillStyle = this.chartUslLabelFillStyle;
        context.textBaseline = "bottom";
        var uslLabel = "USL:" + this.usl;
        var uslLabelLength = context.measureText(uslLabel).width + this.chartSpecLabelMarginRight;
        context.fillText(uslLabel, this.chartWidth - uslLabelLength, this.chartHeight * (this.upl - this.usl) / (this.upl - this.lpl));
        // 画控制图的上控制线(虚线）
        var partCount = Math.round(this.chartWidth / (2 * this.chartDottedLineWidth));
        context.lineWidth = this.chartSpecLineWidth;
        context.strokeStyle = this.chartUclLineStrokeStyle;
        var dottedLineStartX = 0;
        for ( var i = 0; i < partCount; i++) {
            context.beginPath();
            context.moveTo(dottedLineStartX, this.chartHeight * (this.upl - this.ucl) / (this.upl - this.lpl));
            context.lineTo(dottedLineStartX + this.chartDottedLineWidth, this.chartHeight * (this.upl - this.ucl) / (this.upl - this.lpl));
            context.stroke();
            dottedLineStartX += 2 * this.chartDottedLineWidth;
        }

            // 画控制图的上控制线标签
            context.font = this.chartSpecLabelFontStyle + " " + this.chartSpecLabelFontHeight + "px " + this.chartSpecLabelFont;
            context.fillStyle = this.chartUclLabelFillStyle;
            context.textBaseline = "bottom";
            var uclLabel = "UCL:" + this.ucl;
            var uclLabelLength = context.measureText(uclLabel).width + this.chartSpecLabelMarginRight;
            context.fillText(uclLabel, this.chartWidth - uclLabelLength, this.chartHeight * (this.upl - this.ucl) / (this.upl - this.lpl));

        // 画控制图的目标线
        context.beginPath();
        context.lineWidth = this.chartSpecLineWidth;
        context.strokeStyle = this.chartTargetLineStrokeStyle;
        context.moveTo(this.chartWidth, this.chartHeight * (this.upl - this.target) / (this.upl - this.lpl));
        context.lineTo(0, this.chartHeight * (this.upl - this.target) / (this.upl - this.lpl));
        context.stroke();

        // 画控制图的目标线标签
        context.font = this.chartSpecLabelFontStyle + " " + this.chartSpecLabelFontHeight + "px " + this.chartSpecLabelFont;
        context.fillStyle = this.chartTargetLabelFillStyle;
        context.textBaseline = "bottom";
        var targetLabel = "Target:" + this.target;
        var targetLabelLength = context.measureText(targetLabel).width + this.chartSpecLabelMarginRight;
        context.fillText(targetLabel, this.chartWidth - targetLabelLength, this.chartHeight * (this.upl - this.target) / (this.upl - this.lpl));

        // 画控制图的下控制线(虚线）
        var partCount = Math.round(this.chartWidth / (2 * this.chartDottedLineWidth));
        context.lineWidth = this.chartSpecLineWidth;
        context.strokeStyle = this.chartLclLineStrokeStyle;
        var dottedLineStartX = 0;
        for ( var i = 0; i < partCount; i++) {
            context.beginPath();
            context.moveTo(dottedLineStartX, this.chartHeight * (this.upl - this.lcl) / (this.upl - this.lpl));
            context.lineTo(dottedLineStartX + this.chartDottedLineWidth, this.chartHeight * (this.upl - this.lcl) / (this.upl - this.lpl));
            context.stroke();
            dottedLineStartX += 2 * this.chartDottedLineWidth;
        }

            // 画控制图的下控制线标签
            context.font = this.chartSpecLabelFontStyle + " " + this.chartSpecLabelFontHeight + "px " + this.chartSpecLabelFont;
            context.fillStyle = this.chartLclLabelFillStyle;
            context.textBaseline = "bottom";
            var lclLabel = "LCL:" + this.lcl;
            var lclLabelLength = context.measureText(lclLabel).width + this.chartSpecLabelMarginRight;
            context.fillText(lclLabel, this.chartWidth - lclLabelLength, this.chartHeight * (this.upl - this.lcl) / (this.upl - this.lpl));

        // 画控制图的下规格线
        context.beginPath();
        context.moveTo(0, this.chartHeight * (this.upl - this.lsl) / (this.upl - this.lpl));
        context.lineTo(this.chartWidth, this.chartHeight * (this.upl - this.lsl) / (this.upl - this.lpl));
        context.lineWidth = this.chartSpecLineWidth;
        context.strokeStyle = this.chartLslLineStrokeStyle;
        context.stroke();

        // 画控制图的下规格线标签
        context.font = this.chartSpecLabelFontStyle + " " + this.chartSpecLabelFontHeight + "px " + this.chartSpecLabelFont;
        context.fillStyle = this.chartLslLabelFillStyle;
        context.textBaseline = "bottom";
        var lslLabel = "LSL:" + this.lsl;
        var lslLabelLength = context.measureText(lslLabel).width + this.chartSpecLabelMarginRight;
        context.fillText(lslLabel, this.chartWidth - lslLabelLength, this.chartHeight * (this.upl - this.lsl) / (this.upl - this.lpl));

        context.restore();
    };

    //画控制图的上下管控线
    this.drawCL = function () {
        var context = this.context;
        context.save();
        context.translate(this.chartTopLeftX, this.chartTopLeftY);
        var point = this.data.point;

        var  dataPointX = this.chartDataPointGap;
      /*  for ( var i = 0; i < point.length; i++) {
            // dataPointY = this.chartHeight * (1 - (point[i].value / (this.upl - this.lpl))) ;
            var dataPointY = this.chartHeight * (1 - ( (point[i].chart_ucl_fk-this.lpl)/(this.upl - this.lpl) ) ) ;
            if(i == 25 ){
                //画第一个点的延伸线
                context.beginPath();
                context.lineWidth = this.chartSpecLineWidth;
                context.strokeStyle = this.chartUclLineStrokeStyle;
                context.moveTo(dataPointX,dataPointY);
                context.lineTo(0,dataPointY);
                context.stroke();
            }
            if (i > 25) {
                // dataPointYPrevious =  this.chartHeight * (1 - (point[i - 1].value / (this.upl - this.lpl)));
                var dataPointYPrevious =  this.chartHeight * (1 - ( (point[i-1].chart_ucl_fk-this.lpl)/(this.upl - this.lpl) ) ) ;
                context.beginPath();
                context.lineWidth = this.chartSpecLineWidth;
                context.strokeStyle = this.chartUclLineStrokeStyle;
                context.moveTo(dataPointX, dataPointY);
                context.lineTo(dataPointX - this.chartDataPointGap, dataPointYPrevious);
                context.stroke();
            }
            dataPointX += this.chartDataPointGap;
        }*/

        //画最后一点到最右边的延伸线
        var partCount = Math.round(this.chartWidth / (2 * this.chartDottedLineWidth));
        var dataPy = this.chartHeight * (1 - ( (point[point.length-1].chart_ucl_fk-this.lpl)/(this.upl - this.lpl) ) );
        context.lineWidth = this.chartSpecLineWidth;
        context.strokeStyle = this.chartUclLineStrokeStyle;
        var dottedLineStartX = 0;
        for ( var i = 0; i < partCount; i++) {
            context.beginPath();
            context.moveTo(dottedLineStartX, dataPy);
            context.lineTo(dottedLineStartX + this.chartDottedLineWidth, dataPy);
            context.stroke();
            dottedLineStartX += 2 * this.chartDottedLineWidth;
        }

            // 画控制图的上控制线标签
            context.font = this.chartSpecLabelFontStyle + " " + this.chartSpecLabelFontHeight + "px " + this.chartSpecLabelFont;
            context.fillStyle = this.chartUclLabelFillStyle;
            context.textBaseline = "bottom";
            var uclLabel = "UCL:" + point[point.length-1].chart_ucl_fk.toFixed(2);
            var uclLabelLength = context.measureText(uclLabel).width + this.chartSpecLabelMarginRight;
            context.fillText(uclLabel, this.chartWidth - uclLabelLength, this.chartHeight * (this.upl - point[point.length-1].chart_ucl_fk) / (this.upl - this.lpl));
            context.restore();

        //下管控线
        context.save();
        context.translate(this.chartTopLeftX, this.chartTopLeftY);
        var dataPointx = this.chartDataPointGap;

        /*for ( var i = 0; i < point.length; i++) {
            //fix by lin.xin
            // dataPointY = this.chartHeight * (1 - (point[i].value / (this.upl - this.lpl))) ;
            var dataPointY = this.chartHeight * (1 - ( (point[i].chart_lcl_fk-this.lpl)/(this.upl - this.lpl) ) ) ;
            if(i == 25 ){
                //第一个数据和左边Y轴距离30
                context.beginPath();
                context.lineWidth = this.chartSpecLineWidth;
                context.strokeStyle = this.chartUclLineStrokeStyle;
                context.moveTo(dataPointx,dataPointY);
                context.lineTo(0,dataPointY);
                context.stroke();
            }
            if (i > 25) {
                //第二个点开始
                // dataPointYPrevious =  this.chartHeight * (1 - (point[i - 1].value / (this.upl - this.lpl)));
                var dataPointYPrevious =  this.chartHeight * (1 - ( (point[i-1].chart_lcl_fk-this.lpl)/(this.upl - this.lpl) ) ) ;
                context.beginPath();
                context.lineWidth = this.chartSpecLineWidth;
                context.strokeStyle = this.chartUclLineStrokeStyle;
                context.moveTo(dataPointx, dataPointY);
                context.lineTo(dataPointx - this.chartDataPointGap, dataPointYPrevious);
                context.stroke();
            }
            dataPointx += this.chartDataPointGap;
        }
*/
        //画最后一点到最右边的延伸线
        var partCount = Math.round(this.chartWidth / (2 * this.chartDottedLineWidth));
        var dataPy = this.chartHeight * (1 - ( (point[point.length-1].chart_lcl_fk-this.lpl)/(this.upl - this.lpl) ) );
        context.lineWidth = this.chartSpecLineWidth;
        context.strokeStyle = this.chartUclLineStrokeStyle;
        var dottedLineStartX = 0;
        for ( var i = 0; i < partCount; i++) {
            context.beginPath();
            context.moveTo(dottedLineStartX, dataPy);
            context.lineTo(dottedLineStartX + this.chartDottedLineWidth, dataPy);
            context.stroke();
            dottedLineStartX += 2 * this.chartDottedLineWidth;
        }

            // 画控制图的下控制线标签
            context.font = this.chartSpecLabelFontStyle + " " + this.chartSpecLabelFontHeight + "px " + this.chartSpecLabelFont;
            context.fillStyle = this.chartUclLabelFillStyle;
            context.textBaseline = "bottom";
            var lclLabel  = "LCL:" + point[point.length-1].chart_lcl_fk.toFixed(2);
            var lclLabelLength  = context.measureText(lclLabel).width + this.chartSpecLabelMarginRight;
            context.fillText(lclLabel, this.chartWidth - lclLabelLength, this.chartHeight * (this.upl - point[point.length-1].chart_lcl_fk) / (this.upl - this.lpl));
            context.restore();
    };

    // 画控制图的数据点
    this.drawPoint = function(dataArray) {
        var context = this.context;
        context.save();
        context.translate(this.chartTopLeftX, this.chartTopLeftY);
        var point;
        if(typeof(dataArray) == "undefined"){
            point = this.data.point;
        }else{
            point = dataArray.point;
        }

        // 画线
        var dataPointX = this.chartDataPointGap;
        for ( var i = 0; i < point.length; i++) {
            //fix by lin.xin
            // dataPointY = this.chartHeight * (1 - (point[i].value / (this.upl - this.lpl))) ;
            dataPointY = this.chartHeight * (1 - ( (point[i].value-this.lpl)/(this.upl - this.lpl) ) ) ;
            if (i > 0) {
                // dataPointYPrevious =  this.chartHeight * (1 - (point[i - 1].value / (this.upl - this.lpl)));
                dataPointYPrevious =  this.chartHeight * (1 - ( (point[i-1].value-this.lpl)/(this.upl - this.lpl) ) ) ;
                context.strokeStyle = this.chartDataPointLineFillStyle;
                context.beginPath();
                context.moveTo(dataPointX, dataPointY);
                context.lineTo(dataPointX - this.chartDataPointGap, dataPointYPrevious);
                context.stroke();
            }
            dataPointX += this.chartDataPointGap;
        }

        // 画点
		var dataPointCoordinateArray = new Array();
        dataPointX = this.chartDataPointGap;
        for ( var i = 0; i < point.length; i++) {
            // context.save();
            // dataPointY = Math.round(this.chartHeight * (1 - (point[i].value / (this.upl - this.lpl))));
            dataPointY = Math.round(this.chartHeight * (1 - ( (point[i].value-this.lpl) / (this.upl - this.lpl))));
            context.fillStyle = this.chartDataPointFillStyle;
            // console.log("val:"+point[i].value + ",usl:" + this.usl +",lsl:" +this.lsl);
            //大于usl  小于lsl 红色
            if( (this.usl != null && point[i].value > this.usl ) || ( this.lsl != null && point[i].value < this.lsl ) ){
                context.fillStyle ="red";
                console.info("oos");
            }
            //检查是否违反 we rule，如果违反 ： 红色
            if(this.isBreakRule(point[i])){
                context.fillStyle = "red" ;
            }
            context.beginPath();
            context.arc(dataPointX, dataPointY, this.chartDataPointRadius, 0, Math.PI * 2, false);
            var dataPointCoordinate = new Object();
            dataPointCoordinate.x = dataPointX;
            dataPointCoordinate.y = dataPointY;
            dataPointCoordinateArray.push(dataPointCoordinate);//marked by xinlin
            this.dataPointCoordinateArray.push(dataPointCoordinate);//alert by xinlin
            context.closePath();
            context.fill();
            // context.restore();
            //marked by lin.xin
            // if (i == Math.round(point.length / 2)) {
            // 	this.drawTriangle(dataPointX, dataPointY);
            // }
            dataPointX += this.chartDataPointGap;
        }
		this.dataPointCoordinateOneTwoThree.push(dataPointCoordinateArray);
        context.restore();
    };

    this.isMainChart = function(){
        var chartTyp = this.chart_typ;
        return chartTyp == "01" || chartTyp == "10" || chartTyp=='30'||chartTyp=='40'||chartTyp=='50'||chartTyp=='60';
    };

    this.isBreakRule = function(point){
        var ruleRlt = point.chart_rule1_rlt_fk;
        var chartTyp = this.chart_typ;

        if (this.isMainChart() && ruleRlt) {
            return ruleRlt.indexOf("Y") == -1 ? false : true;
        }
        return false;
    },
        // 画三角形的函数
    this.drawTriangle = function(x, y) {
            var context = this.context;
            context.save();
            var r = this.chartPointCommentTriangleRadius;
            var context = this.context;
            context.beginPath();
            context.moveTo(x - Math.sin(Math.PI / 3) * r, y + r / 2);
            context.lineTo(x, y - r);
            context.lineTo(x + Math.sin(Math.PI / 3) * r, y + r / 2);
            context.lineTo(x - Math.sin(Math.PI / 3) * r, y + r / 2);
            context.closePath();
            context.fillStyle = this.chartPointCommentTriangleFillStyle;
            context.fill();
            context.restore();
        };

    this.activateClickEvent = function() {
        var context = this.context;
        var _this = this;
        var selectedFlag = false;

        // 很重要！！！
        $('#chart').unbind("click");
        $("#chart").click(function(event) {

            // 判断点击的是哪个控制图
            var canvasInnerCoordinateY = event.pageY - _this.canvas.offsetTop;
            switch (_this.chartCount) {
                case 1:
                    _this.clickChartSequence = 1;
                    break;
                case 2:
                    if (canvasInnerCoordinateY < _this.tileHeight) {
                        _this.clickChartSequence = 1;
                    } else {
                        _this.clickChartSequence = 2;
                    }
                    break;
                case 3:
                    if (canvasInnerCoordinateY < _this.tileHeight) {
                        _this.clickChartSequence = 1;
                    } else if (_this.tileHeight < canvasInnerCoordinateY < _this.tileHeight * 2) {
                        _this.clickChartSequence = 2;
                    } else {
                        _this.clickChartSequence = 3;
                    }
                    break;
            }

            // 控制图点选中后画一条经过数据点的竖线
            var mouseClickX = event.pageX - _this.canvas.offsetLeft - _this.chartTopLeftForFirstChartX;
            var mouseClickY = event.pageY - _this.canvas.offsetTop - _this.tileHeight * (_this.clickChartSequence - 1) - _this.chartTopLeftForFirstChartY;
            var dataPointCoordinateX = 0;
            var dataPointCoordinateY = 0;
            var dataPointRadius = _this.chartDataPointRadius;
            if (selectedFlag) {
                _this.canvas.width = _this.canvas.width;
                for ( var i = 0; i < _this.chartCount; i++) {
                    _this.initializeChart(_this.data, _this.chartCount, i + 1);
                    _this.drawPoint(_this.data.point);
                }
            }
            for ( var i = 0; i < _this.dataPointCoordinateOneTwoThree[_this.clickChartSequence - 1].length; i++) {
                dataPointCoordinateX = _this.dataPointCoordinateOneTwoThree[_this.clickChartSequence - 1][i].x;
                dataPointCoordinateY = _this.dataPointCoordinateOneTwoThree[_this.clickChartSequence - 1][i].y;
                if (Math.abs(mouseClickX - dataPointCoordinateX) <= dataPointRadius && Math.abs(mouseClickY - dataPointCoordinateY) <= dataPointRadius) {
                    $("#inputTimeStampTxt").attr("value", _this.data.point[i].inputTimestamp);
                    $("#pointValueTxt").attr("value", _this.data.point[i].value);
                    $("#prdInfoSeqTxt").attr("value", _this.data.point[i].glassId);
                    $("#pToolIDTxt").attr("value", _this.data.point[i].processEqptId);
                    $("#mToolIDTxt").attr("value", _this.data.point[i].measurementEqptId);
                    $("#commentTxt").attr("value", _this.data.point[i].comment);
                    for ( var j = 0; j < _this.chartCount; j++) {
                        context.save();
                        context.translate(_this.chartTopLeftForFirstChartX, _this.chartTopLeftForFirstChartY + _this.tileHeight * j);
                        context.lineWidth = _this.dataPointSelectedLineWidth;
                        context.beginPath();
                        context.moveTo(dataPointCoordinateX, 0);
                        context.lineTo(dataPointCoordinateX, _this.chartHeight);
                        context.strokeStyle = _this.dataPointSelectedLineStrokeStyle;
                        context.lineWidth = _this.dataPointSelectedLineWidth;
                        context.stroke();
                        context.restore();
                        selectedFlag = true;
                    }
                    break;
                }
            }
        });
    };


    this.caclCPk = function(){
        this.mean = sum/pointCnt;
        this.stdDev =0;
        this.sigma  =0;
        this.ppk=0;
        this.pp=0;
        this.ca =0;
        this.cpk=0;
        this.cp=0;
        this.grade="A";

        var point = this.data.point;
        if(point.length<2){
            showErrorDialog("003","数据小于两行,不能计算CPK");
            return false;
        }
        //计算mean
        var sum = 0;
        var pointCnt = point.length ;
        for(var i=0;i<pointCnt;i++){
            sum = sum + point[i].value;
        }
        this.mean = sum/pointCnt;
        //计算sigma
        // Math.pow() -- 返回底数的指定次幂
        // Math.sqrt() -- 返回数字的平方根
        var tmpSquSum=0;
        for(var i=0;i<pointCnt;i++){
            tmpSquSum = tmpSquSum + Math.pow( (point[i].value-this.mean) , 2);
        }
        this.sigma = Math.sqrt( tmpSquSum /(pointCnt-1) );
        //计算ca
        if(this.usl != null && this.lsl !=null ){
            this.ca = Math.abs((this.mean - this.target)/(0.5* (this.usl-this.lsl)));
        }else{
            this.ca =null;
        }
        //计算cp
        if(this.usl!=null && this.lsl==null){
            this.cp = (this.usl-this.mean)/(3*this.sigma);
        }else if(this.usl==null && this.lsl!=null){
            this.cp = (this.mean-this.lsl)/(3*this.sigma);
        }else if(this.usl!=null && this.lsl!=null){
            this.cp = (this.usl-this.lsl)/(6*this.sigma);
        }else{
            this.cp=null;
        }
        //计算cpk
        // Math.abs() -- 返回数字的绝对值

        cpl = (this.mean - this.lsl) / (6 * this.sigma);
        cpu = (this.usl - this.mean) / (6 * this.sigma);

        this.cpk = cpl > cpu ? cpu : cpl;
//		if(this.ca ==null){
//			this.cpk = this.cp;
//		}else if(this.cp==null){
//			this.cpk = null;
//		}else{
//			this.cpk = (1-Math.abs(this.ca))*this.cp;
//		}
        //计算 sigma_ppk
        if(this.chart_typ=="01"){
            var tmpSumSum_ppk=0;
            var pointCnt = this.data.point.length;
            var sampleSize = this.data.point[0].rawData.length;
            for(var i=0;i<pointCnt;i++){
                var tmpSum_ppk=0;
                for(var j=0;j<this.data.point[i].rawData.length;j++){
                    var rawValue =  this.data.point[i].rawData[j].prd_raw_value;
                    tmpSum_ppk = tmpSum_ppk + Math.pow(( rawValue - this.mean),2);
                }
                tmpSumSum_ppk = tmpSumSum_ppk + tmpSum_ppk;
            }
            this.sigma_ppk  = Math.sqrt(tmpSumSum_ppk/(pointCnt*sampleSize-1));

            //计算 pp
            if( this.usl !=null && this.lsl !=null ){
                this.pp = (this.usl-this.lsl)/(this.sigma_ppk*6);
            }else if(this.usl!=null&& this.lsl==null){
                this.pp = (this.usl - this.mean)/(this.sigma_ppk*3);
            }else if(this.usl ==null && this.lsl !=null ){
                this.pp = (this.mean-this.lsl)/(this.sigma_ppk*3);
            }
            //计算 ppk
            if(this.usl!=null && this.lsl!=null){
                this.ppk = (1-Math.abs(this.ca) ) * this.pp;
            }else{
                this.ppk = this.pp;
            }

        }else{
            this.sigma_ppk = this.sigma ;
        }

        //
        //计算grade
        if(this.cpk>=1.67){
            this.grade = "A+";
        }else if(this.cpk>=1.33){
            this.grade = "A";
        }else if(this.cpk>=1.00){
            this.grade = "B";
        }else if(this.cpk>=0.67){
            this.grade = "C";
        }else{
            this.grade = "E";
        }
        this.mean = this.formatFloat(this.mean);
        this.sigma = this.formatFloat(this.sigma);
        this.ca  = this.formatFloat(this.ca);
        this.cp  = this.formatFloat(this.cp);
        this.cpk  = this.formatFloat(this.cpk);
        this.pp = this.formatFloat(this.pp);
        this.ppk = this.formatFloat(this.ppk);
    };


    this.formatFloat=function( dbl ){
//		if(dbl===0){
//			return -1;
//		}
        var strDbl = dbl + "";
        var index = strDbl.indexOf(".");
        if(index===-1){
            return strDbl+".000";
        }
        var strRight = strDbl.substr(index+1);
        var strLeft  = strDbl.substr(0,index);
        if(strRight.length>3){
            return strDbl.substr(0,index+4);
        }else{
            return strLeft+"."+ this.ComL2S(strRight, 3, "0")
        }

    };


    this.ComL2S = function(data1,length,data2){
        if(length<=0){
            return null;
        }
        var str = data1.toString();
        if( data1.length > length){
            return null;
        }
        var size = str.length;
        var chazhi = length - size;
        for(var i =0;i<chazhi;i++){
            str = str+data2;
        }
        return str;
    };

}

//add by xinlin
var Page = function(){
    this.chartList = new Array();
    this.canvas ={};
    this.clickChartSequence=1;
    this.chartCount = 0;
    this.activeChart ={};
    this.addChart = function(chart,length){
        this.chartList.push(chart);
        this.canvas=chart.canvas;
        if(length > 1){
            this.chartCount = 1;//如果选择了多张图，则设置1
        }else {
            this.chartCount++;
        }
    };

    this.activateClickEvent = function(chartName,length) {
        var _this = this;

        var selectedFlag = false;
        var C;
        if(typeof(chartName) !=="undefined"){
            if(chartName === "chart0"){
                C = 1;
            }else if(chartName === "chart1"){
                C = 2;
            }else if(chartName === "chart2"){
                C = 3;
            }
        }

        // 很重要！！！
//		$('#chart').unbind("click");
//		$("#chart").click(function(event) {
//		$("#chart").unbind("mousedown");
//		$("#chart").mousedown(function(e){
        $("#" + chartName+ "").unbind("contextmenu");
        $("#" + chartName+ "").bind("contextmenu", function(event){
//			if(e.which != 3){
//				return ;
//			}
            // 判断点击的是哪个控制图
            var canvasInnerCoordinateY = event.pageY - _this.canvas.offsetTop;

            switch (_this.chartCount) {
                case 1:
                    _this.clickChartSequence = 1;
                    if(length > 1){
                        _this.activeChart = _this.chartList[C-1];
                    }else{
                        _this.activeChart = _this.chartList[0];
                    }
                    break;
                case 2:
                    if (canvasInnerCoordinateY < _this.chartList[0].tileHeight) {
                        _this.clickChartSequence = 1;
                        _this.activeChart = _this.chartList[0];
                    } else {
                        _this.clickChartSequence = 2;
                        _this.activeChart = _this.chartList[1];
                    }
                    break;
                case 3:
                    if (canvasInnerCoordinateY < _this.tileHeight) {
                        _this.clickChartSequence = 1
                        _this.activeChart = _this.chartList[0];;
                    } else if (_this.tileHeight < canvasInnerCoordinateY < _this.tileHeight * 2) {
                        _this.clickChartSequence = 2;
                        _this.activeChart = _this.chartList[1];
                    } else {
                        _this.clickChartSequence = 3;
                        _this.activeChart = _this.chartList[2];
                    }
                    break;
            }
            var context = _this.activeChart.context;

            // 控制图点选中后画一条经过数据点的竖线
            var bugGap = 30*(_this.clickChartSequence-1);
            var mouseClickX = event.pageX - _this.canvas.offsetLeft - _this.activeChart.chartTopLeftForFirstChartX-bugGap;
            if(length > 1){
                var mouseClickY = event.pageY - (_this.canvas.offsetTop-(length-1)*280) - _this.activeChart.tileHeight * (_this.clickChartSequence - 1) - _this.activeChart.chartTopLeftForFirstChartY-bugGap -(C-1)*280;
            }else{
                var mouseClickY = event.pageY - _this.canvas.offsetTop - _this.activeChart.tileHeight * (_this.clickChartSequence - 1) - _this.activeChart.chartTopLeftForFirstChartY-bugGap;
            }


            var dataPointCoordinateX = 0;
            var dataPointCoordinateY = 0;
            var dataPointRadius = _this.activeChart.chartDataPointRadius;
            for ( var i = 0; i < _this.activeChart.dataPointCoordinateArray.length; i++) {
                dataPointCoordinateX = _this.activeChart.dataPointCoordinateArray[i].x;
                dataPointCoordinateY = _this.activeChart.dataPointCoordinateArray[i].y;
                if (Math.abs(mouseClickX - dataPointCoordinateX) <= dataPointRadius && Math.abs(mouseClickY - dataPointCoordinateY) <= dataPointRadius) {
                    var point = _this.activeChart.data.point[i];
                    var selectChartData = {
                        report_timestamp : point.inputTimestamp.replace("T"," "),
                        reporter         : point.reporter,
                        glass_id         : point.glassId,
                        proc_eqpt_id     : point.processEqptId,
                        chart_value      : point.value,
                        chart_rule_1_rlt : point.chart_rule_1_rlt

                    }
                    _this.mouseRightClick($.extend(selectChartData,point),_this,i);
//					$("#inputTimeStampTxt").attr("value", _this.activeChart.data.point[i].inputTimestamp.replace("T"," "));
//					$("#pointValueTxt").attr("value", _this.activeChart.data.point[i].value);
//					$("#prdInfoSeqTxt").attr("value", _this.activeChart.data.point[i].glassId);
//					$("#pToolIDTxt").attr("value", _this.activeChart.data.point[i].processEqptId);
//					$("#mToolIDTxt").attr("value", _this.activeChart.data.point[i].measurementEqptId);
//					$("#commentTxt").attr("value", _this.activeChart.data.point[i].comment);
//					for ( var j = 0; j < _this.chartCount; j++) {
//						context.save();
//						context.translate(_this.activeChart.chartTopLeftForFirstChartX, _this.activeChart.chartTopLeftForFirstChartY + _this.activeChart.tileHeight * j);
//						context.lineWidth = _this.activeChart.dataPointSelectedLineWidth;
//						context.beginPath();
//						context.moveTo(dataPointCoordinateX, 0);
//						context.lineTo(dataPointCoordinateX, _this.chartHeight);
//						context.strokeStyle = _this.activeChart.dataPointSelectedLineStrokeStyle;
//						context.lineWidth = _this.activeChart.dataPointSelectedLineWidth;
//						context.stroke();
//						context.restore();
//						selectedFlag = true;
//					}
                    break;
                }
            }
//			e.preventDefault();
            return false;
        });
    };
    this.mouseRightClick = function(data,_this,index){

        var chartRuleRlt = data.chart_rule_1_rlt_fk;
        var comment = data.chart_comment ? data.chart_comment : "";

        var str = '<div id = "pointInfoModal" class="modal fade">';
        str+='<div class="modal-dialog">';
        str+='<div class="modal-content">';
        str += '<div class="modal-header">';
        str +='<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>';
        str +='</div>';
        str +='<div class="modal-body">';
        str += "<table class='table table-striped'><caption>详细信息</caption>";
//		  str += "<thead><tr><th>项目</th><th>值</th></tr></thead>"
        str += "<tr><td>序列</td><td>"+ (index+1) +"</td>";
        str += "<tbody><tr><td>上报时间</td><td>"+ 	data.report_timestamp + "</td></tr>";
        str += "<tr><td>上报人</td><td>" + data.reporter + "</td></tr>";
        str += "<tr><td>玻璃代码</td><td>" + data.glass_id + "</td></tr>";
        str += "<tr><td>制程机台</td><td>" + data.proc_eqpt_id + "</td></tr>";
        str += "<tr><td>数据点值</td><td>" + data.chart_value + "</td></tr>";
        if(typeof(data.ucl) !== "undefined" && typeof(data.lcl) !== "undefined"){
            str += "<tr><td>上控制线</td><td>" + data.ucl.toFixed(2) + "</td></tr>";
            str += "<tr><td>下控制线</td><td>" + data.lcl.toFixed(2) + "</td></tr>";
        }



        str += "<tr><td>备注</td><td><input id='commentTxt' type='text' value= '" + comment + "' /> <button id='addCommentBtn' class='btn btn-info' >添加备注</button></td></tr>"
        str += "<tr style='display:none'><td>col_typ_fk</td><td id='colTypTd'>"+ data.col_typ_fk  +"</td></tr>"
        str += "<tr style='display:none'><td>grp_no_fk</td><td id='grpNoTd'>"+ data.grp_no_fk  +"</td></tr>"
        str += "<tr style='display:none'><td>chart_no_fk</td><td id='chartNoTd'>"+ data.chart_no_fk  +"</td></tr>"
        str += "<tr style='display:none'><td>chart_typ_fk</td><td id='chartTypTd'>"+ data.chart_typ_fk  +"</td></tr>"
        str += "<tr style='display:none'><td>input_time_d</td><td id='inputTimeDTd'>"+ data.input_time_d  +"</td></tr>"


        if(chartRuleRlt){
            var chartRule1 = chartRuleRlt[0];
            if(chartRule1 && chartRule1 === "Y"){
                str += "<tr><td>超规</td><td>一点跳出管界限外</td></tr>";
            }
            var chartRule2 = chartRuleRlt[1];
            if(chartRule2 && chartRule2 === "Y"){
                str += "<tr><td>超规</td><td color='red'>连续八点落在中心线同一侧</td></tr>";
            }
            var chartRule3 = chartRuleRlt[2];
            if(chartRule3 && chartRule3 === "Y"){
                str += "<tr><td>超规</td><td color='red'>连续六点上升或下降</td></tr>";
            }
            var chartRule4 = chartRuleRlt[3];
            if(chartRule4 && chartRule4 === "Y"){
                str += "<tr><td>超规</td><td color='red'>连续十四点交互着上下跳动</td></tr>";
            }
            var chartRule5 = chartRuleRlt[4];
            if(chartRule5 && chartRule5 === "Y"){
                str += "<tr><td>超规</td><td color='red'>连续三点有两点落在2σ以外</td></tr>";
            }
            var chartRule6 = chartRuleRlt[5];
            if(chartRule6 && chartRule6 === "Y"){
                str += "<tr><td>超规</td><td color='red'>连续五点中有四点落在1σ外</td></tr>";
            }
            var chartRule7 = chartRuleRlt[6];
            if(chartRule7 && chartRule7 === "Y"){
                str += "<tr><td>超规</td><td color='red'>连续十五点在中心线上下两侧1σ以内</td></tr>";
            }

        }
        str += "</tbody></table>";
        str +='</div>';
        str +='<div class="modal-footer">';
//		  str +='<a href="#" class="btn">关闭</a>';
//		  str +=' <a href="#" class="btn btn-primary">Save changes</a>';
        str +='</div>';
        str +='</div>';
        str +='</div>';
        str +='</div>';
        if($("#pointInfoModal").length>0){
            $("#pointInfoModal").remove();
        }
        $(str).appendTo("body");

        $("#pointInfoModal").modal({keyboard:true});
        $("#pointInfoModal").modal("show");


        $("#addCommentBtn").unbind("click");
        $("#addCommentBtn").bind("click",function(){
            var colTyp = $("#colTypTd").text(),
                grpNo = $("#grpNoTd").text(),
                chartNo = $("#chartNoTd").text(),
                chartTyp = $("#chartTypTd").text(),
                inputTimeD = $("#inputTimeDTd").text();
            comment = $("#commentTxt").val();

            if(!comment){
                showErrorDialog("","请输入要备注信息");
                return false;
            }

       /*     $.ajax({
                type : "POST",
                url : "addChartComment",
                timeout : 60000,
                async : false, // false代表等待ajax执行完毕后才执行success中语句;
                data : {
                    col_typ:colTyp,
                    grp_no:grpNo,
                    chart_no:chartNo,
                    chart_typ:chartTyp,
                    inputTimeD:inputTimeD,
                    comment:comment
                },
                beforeSend : function() {
                },
                complete : function() {// ajaxStop改为ajaxComplete也是一样的
                },
                success : function(data) {
                    showSuccessDialog("添加备注成功");
                    _this.activeChart.data.point[index].chart_comment = comment;
                }
            });*/
            var inTrxObj = {
                trx_id     : "XPCCHTDT",
                action_flg : "A",
                col_typ:colTyp,
                grp_no:grpNo,
                chart_no:chartNo,
                chart_typ:chartTyp,
                input_time_d:inputTimeD,
                comment:comment
            };
            var outTrxObj = comTrxSubSendPostJson(inTrxObj);
            if(outTrxObj.rtn_code=="0000000"){
                showSuccessDialog("添加备注成功");
                _this.activeChart.data.point[index].chart_comment = comment;
            }

        });

        return false;
    }


}
